package com.zlc.common.aop;

import com.zlc.common.common.exception.BusinessException;
import com.zlc.common.common.service.ContextHolder;
import com.zlc.common.util.PlatUtils;
import com.zlc.common.util.UserHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.zlc.common.common.constant.PlatConstant.AOP_KEY_WORD;


/**
 * @author zl
 */
@Slf4j
@Aspect
@Component
@SuppressWarnings("unchecked")
public class PersistenceAop {

    @Before("execution(* com.zlc.common..service..saveVo*(..))")
    public void saveAop(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        if (args.length > 0) {
            Object arg = args[0];

            if (arg instanceof List) {
                ArrayList list = (ArrayList)arg;
                list.forEach(PersistenceAop::addField);
            } else {
                PersistenceAop.addField(arg);
            }
        }
    }


    public static void addField(Object o) {
        try {
            Object keyWord = ContextHolder.get(AOP_KEY_WORD);
            if (keyWord != null) {
                return;
            }
            Class<?> clazz = o.getClass().getSuperclass();

            Field idField = clazz.getDeclaredField("id");
            idField.setAccessible(true);
            Object id = idField.get(o);
            if (id == null || StringUtils.isBlank((String)id)) {
                idField.set(o, PlatUtils.uuid());
            }

            // 设置通用属性
            String userName = UserHelper.getNowAccount();
            if (userName == null) {
                userName = ContextHolder.get("logAccount");
            }

            if (userName == null) {
                userName = "SYSTEM";
            }


            Field updatedByField = clazz.getDeclaredField("updateUser");
            updatedByField.setAccessible(true);
            updatedByField.set(o, userName);

            Field dateUpdatedField = clazz.getDeclaredField("updateTime");
            dateUpdatedField.setAccessible(true);
            dateUpdatedField.set(o, new Date());

            Field createdByField = clazz.getDeclaredField("createUser");
            createdByField.setAccessible(true);
            if (createdByField.get(o) == null) {
                createdByField.set(o, userName);
            }

            Field dateCreated = clazz.getDeclaredField("createTime");
            dateCreated.setAccessible(true);
            if (dateCreated.get(o) == null) {
                dateCreated.set(o, new Date());
            }

        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
    }



}
